#include <iostream>
#include <fstream>
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <string>

using namespace std;

// Include GLEW
#include <GL/glew.h>

// Include GLFW
#include <GL/glfw.h>

// Include GLUT
#include <GL/glut.h>

// Include GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtx/quaternion.hpp>
#include <glm/gtx/euler_angles.hpp>
#include <glm/gtx/norm.hpp>

using namespace glm;

#include "shader.hpp"

#include <dirent.h>

#define uint unsigned int

#ifndef SPHERE_HPP
#define SPHERE_HPP

static GLuint programID[2];
static int programsLoaded = 0;

class Map
{
private:
    char *path;

    int LOD;

    char *mappedMap;

    GLuint dataBuffer;
    short *data;
    uint dataBufferSize;

    GLuint *matrixBuffer;
    uint *matrixBufferSize;

    GLuint *elementBuffer;
    uint *elementBufferSize;

    short longitude;    //długość geograficzna
    short latitude;     //szerokość geograficzna

    short useProgram; // use program = view

    GLuint MatrixID[2];
    GLuint CordID[2];

    mat2 cord;

    void loadMap();

    void initMap();
    void initMapGPU();
    void getCoordinates();
public:
    Map(char *_path,
        GLuint *_elementBuffer,
        uint *_elementBufferSize,
        GLuint *_matrixBuffer);

    void drawMap(mat4 VP);

    void setLOD(int _LOD);

    void setView(short _view);

    int getCordX();
    int getCordY();
    int *getLODPointer();
};

class MapsCon
{
private:
    char *path;

    GLuint matrixBuffer;
    short *matrix;
    uint matrixBufferSize;

    GLuint elementBuffer[9];
    unsigned int *element;
    uint elementBufferSize[9];

    Map **map;  //maps in memory
    uint mapSize;

    void lodaMaps();

    int *mpasLOD[360][360];
    void initMapsLODPointers(); //poiters to maps LOD var to change them fast

    void createMapsLOD();
    void createMapsMatrix();

    void setMapsLOD(int _LOD);

public:
    MapsCon(char *_path);

    void drawMaps(mat4 VP);
    void changLOD(int _LOD);

    void changeMapLOD(int _LOD, int x, int y);

    void setViews(short _view); //set view you wont to use
};

#endif
